/*
* ============================================================================
*  Name        : test_hello.cpp
*  Part of     : Finite state machine examples
*  Description : Simple server : thread handling client's requests
*  Version     : %version: %
*  
*
* ============================================================================
*/
#include <sea_statemachine>

using namespace sea;

// -------------------------------------------------------------------------------------------------
// @class Hello
// @brief Simple server handling client's events. 
// -------------------------------------------------------------------------------------------------
class Hello : public StateMachine
{
public:
    Hello( ): StateMachine( STATEMACHINE_NAME ) { log( true ); }

    EVENT_EXT( Hello, Ev_Ext_Event1 );
    EVENT_EXT( Hello, Ev_Ext_Event2 );
    EVENT_EXT( Hello, Ev_Ext_Event3 );

private:
    ACT( Hello, handle_event1 );
    ACT( Hello, handle_event2 );
    ACT( Hello, handle_event3 );
};

// -------------------------------------------------------------------------------------------------
// State-less machine
// -------------------------------------------------------------------------------------------------
SM_DECLARE(
    HelloSourseId,      // Source code identifier
    Hello               // Class name
    async               // Run in a separate thread
    {
        Handler
        {
            Ev_Ext_Event1           handle_event1   nojump 
            Ev_Ext_Event2           handle_event2   nojump 
            Ev_Ext_Event3           handle_event3   nojump 

            Ev_Sys_Terminate        exit            nojump
        }
    } 
);

// -------------------------------------------------------------------------------------------------
// Event handlers
// -------------------------------------------------------------------------------------------------
ACT_IMPL( Hello, handle_event1 )
{
    SEA_UNUSED_PARAM( );
    push_event( Ev_Ext_Event2( ) );
}

ACT_IMPL( Hello, handle_event2 )
{
    SEA_UNUSED_PARAM( );
    push_event( Ev_Ext_Event3( ) );
}

ACT_IMPL( Hello, handle_event3 )
{
    SEA_UNUSED_PARAM( );
    push_event( terminate_event_id( ) );
}

// -------------------------------------------------------------------------------------------------
// Create server
// -------------------------------------------------------------------------------------------------

Hello* create_server( )
{
    Hello* server = NEW Hello;
    if ( server->create( 0, HelloSourseId ) != sea::eOk ) { }
    if ( server->start( ) != sea::eOk ) { }
    
    return server;
}

// -------------------------------------------------------------------------------------------------

// Create and wait for server to terminate
// -------------------------------------------------------------------------------------------------

void test_server( )
{
    Hello* server = create_server( );

    // Now client can send messages to the server
    //
    // Dummy example: Create chain reaction... 
    // Event1 will invoke handle_event1, which generates event2
    // Event2 will invoke handle_event2, which generates event3
    // Event3 will invoke handle_event3, which generates Terminate event
    server->push_event( server->Ev_Ext_Event1( ) );

    server->wait_manager_to_finish( );
    server->release_ref( );

    Engine::terminate( );
}

// -------------------------------------------------------------------------------------------------
